home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / mcr68.c < prev    next >
C/C++ Source or Header  |  2000-04-08  |  19KB  |  750 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/mcr68.c
  4.  
  5.   Xenophobe video hardware very similar to Rampage.
  6.  
  7.   Colour 8 in sprites indicates transparency in closed area.
  8.   Each tile has an attribute to indicate tile drawn on top of sprite.
  9.  
  10. ***************************************************************************/
  11.  
  12. #include "driver.h"
  13. #include "vidhrdw/generic.h"
  14.  
  15.  
  16. #define LOW_BYTE(x) (READ_WORD(x) & 0xff)
  17.  
  18.  
  19. UINT8 mcr68_sprite_clip;
  20. INT8 mcr68_sprite_xoffset;
  21.  
  22.  
  23. #define DEBUG_VIDEO        0
  24.  
  25.  
  26. #if DEBUG_VIDEO
  27. static int show_bg_colors;
  28. static int show_colors;
  29.  
  30. static void mcr68_debug();
  31. static void zwackery_debug();
  32. #endif
  33.  
  34.  
  35.  
  36. /*************************************
  37.  *
  38.  *    Palette RAM writes
  39.  *
  40.  *************************************/
  41.  
  42. WRITE_HANDLER( mcr68_paletteram_w )
  43. {
  44.     int oldword = READ_WORD(&paletteram[offset]);
  45.     int newword = COMBINE_WORD(oldword, data);
  46.     int r, g, b;
  47.  
  48.     WRITE_WORD(&paletteram[offset], newword);
  49.  
  50.     r = (newword >> 6) & 7;
  51.     b = (newword >> 3) & 7;
  52.     g = (newword >> 0) & 7;
  53.  
  54.     /* up to 8 bits */
  55.     r = (r << 5) | (r << 2) | (r >> 1);
  56.     g = (g << 5) | (g << 2) | (g >> 1);
  57.     b = (b << 5) | (b << 2) | (b >> 1);
  58.  
  59.     palette_change_color(offset / 2, r, g, b);
  60. }
  61.  
  62.  
  63.  
  64. /*************************************
  65.  *
  66.  *    Video RAM writes
  67.  *
  68.  *************************************/
  69.  
  70. WRITE_HANDLER( mcr68_videoram_w )
  71. {
  72.     int oldword = READ_WORD(&videoram[offset]);
  73.     int newword = COMBINE_WORD(oldword, data);
  74.  
  75.     if (oldword != newword)
  76.     {
  77.         dirtybuffer[offset & ~3] = 1;
  78.         WRITE_WORD(&videoram[offset], newword);
  79.     }
  80. }
  81.  
  82.  
  83.  
  84. /*************************************
  85.  *
  86.  *    Background update
  87.  *
  88.  *************************************/
  89.  
  90. static void mcr68_update_background(struct osd_bitmap *bitmap, int overrender)
  91. {
  92.     int offs;
  93.  
  94.     /* for every character in the Video RAM, check if it has been modified */
  95.     /* since last time and update it accordingly. */
  96.     for (offs = videoram_size - 4; offs >= 0; offs -= 4)
  97.     {
  98.         /* this works for overrendering as well, since the sprite code will mark */
  99.         /* intersecting tiles for us */
  100.         if (dirtybuffer[offs])
  101.         {
  102.             int mx = (offs / 4) % 32;
  103.             int my = (offs / 4) / 32;
  104.             int attr = LOW_BYTE(&videoram[offs + 2]);
  105.             int color = (attr & 0x30) >> 4;
  106.             int code = LOW_BYTE(&videoram[offs]) + 256 * (attr & 0x03) + 1024 * ((attr >> 6) & 0x03);
  107.  
  108.             if (!overrender)
  109.                 drawgfx(bitmap, Machine->gfx[0], code, color ^ 3, attr & 0x04, attr & 0x08,
  110.                         16 * mx, 16 * my, &Machine->drv->visible_area, TRANSPARENCY_NONE, 0);
  111.             else if (Machine->gfx[0]->total_elements < 0x1000 && (attr & 0x80))
  112.                 drawgfx(bitmap, Machine->gfx[0], code, color ^ 3, attr & 0x04, attr & 0x08,
  113.                         16 * mx, 16 * my, &Machine->drv->visible_area, TRANSPARENCY_PEN, 0);
  114.             else
  115.                 continue;
  116.  
  117.             /* only clear the dirty flag if we're not overrendering */
  118.             dirtybuffer[offs] = 0;
  119.         }
  120.     }
  121. }
  122.  
  123.  
  124.  
  125. /*************************************
  126.  *
  127.  *    Sprite update
  128.  *
  129.  *************************************/
  130.  
  131. static void mcr68_update_sprites(struct osd_bitmap *bitmap, int priority)
  132. {
  133.     struct rectangle sprite_clip = Machine->drv->visible_area;
  134.     int offs;
  135.  
  136.     /* adjust for clipping */
  137.     sprite_clip.min_x += mcr68_sprite_clip;
  138.     sprite_clip.max_x -= mcr68_sprite_clip;
  139.  
  140.     /* loop over sprite RAM */
  141.     for (offs = 0; offs < spriteram_size; offs += 8)
  142.     {
  143.         int code, color, flipx, flipy, x, y, sx, sy, xcount, ycount, flags;
  144.  
  145.         flags = LOW_BYTE(&spriteram[offs + 2]);
  146.         code = LOW_BYTE(&spriteram[offs + 4]) + 256 * ((flags >> 3) & 0x01) + 512 * ((flags >> 6) & 0x03);
  147.  
  148.         /* skip if zero */
  149.         if (code == 0)
  150.             continue;
  151.  
  152.         /* also skip if this isn't the priority we're drawing right now */
  153.         if (((flags >> 2) & 1) != priority)
  154.             continue;
  155.  
  156.         /* extract the bits of information */
  157.         color = ~flags & 0x03;
  158.         flipx = flags & 0x10;
  159.         flipy = flags & 0x20;
  160.         x = LOW_BYTE(&spriteram[offs + 6]) * 2 + mcr68_sprite_xoffset;
  161.         y = (241 - LOW_BYTE(&spriteram[offs])) * 2;
  162.  
  163.         /* allow sprites to clip off the left side */
  164.         if (x > 0x1f0) x -= 0x200;
  165.  
  166.         /* draw the sprite */
  167.         drawgfx(bitmap, Machine->gfx[1], code, color, flipx, flipy, x, y,
  168.                 &sprite_clip, TRANSPARENCY_PEN, 0);
  169.  
  170.         /* sprites use color 0 for background pen and 8 for the 'under tile' pen.
  171.             The color 8 is used to cover over other sprites. */
  172.         if (Machine->gfx[1]->pen_usage[code] & 0x0100)
  173.         {
  174.             struct rectangle clip;
  175.  
  176.             clip.min_x = x;
  177.             clip.max_x = x + 31;
  178.             clip.min_y = y;
  179.             clip.max_y = y + 31;
  180.  
  181.             copybitmap(bitmap, tmpbitmap, 0, 0, 0, 0, &clip, TRANSPARENCY_THROUGH, Machine->pens[8 + color * 16]);
  182.         }
  183.  
  184.         /* mark tiles underneath as dirty for overrendering */
  185.         if (priority == 0)
  186.         {
  187.             sx = x / 16;
  188.             sy = y / 16;
  189.             xcount = (x & 15) ? 3 : 2;
  190.             ycount = (y & 15) ? 3 : 2;
  191.  
  192.             for (y = sy; y < sy + ycount; y++)
  193.                 for (x = sx; x < sx + xcount; x++)
  194.                     if (x >= 0 && x < 32 && y >= 0 && y < 30)
  195.                         dirtybuffer[(32 * y + x) * 4] = 1;
  196.         }
  197.     }
  198. }
  199.  
  200.  
  201.  
  202. /*************************************
  203.  *
  204.  *    General MCR/68k update
  205.  *
  206.  *************************************/
  207.  
  208. void mcr68_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  209. {
  210. #if DEBUG_VIDEO
  211.     mcr68_debug();
  212. #endif
  213.  
  214.     /* update palette */
  215.     if (palette_recalc())
  216.         memset(dirtybuffer, 1, videoram_size);
  217.  
  218.     /* draw the background */
  219.     mcr68_update_background(tmpbitmap, 0);
  220.  
  221.     /* copy it to the destination */
  222.     copybitmap(bitmap, tmpbitmap, 0, 0, 0, 0, &Machine->drv->visible_area, TRANSPARENCY_NONE, 0);
  223.  
  224.     /* draw the low-priority sprites */
  225.     mcr68_update_sprites(bitmap, 0);
  226.  
  227.     /* redraw tiles with priority over sprites */
  228.     mcr68_update_background(bitmap, 1);
  229.  
  230.     /* draw the high-priority sprites */
  231.     mcr68_update_sprites(bitmap, 1);
  232. }
  233.  
  234.  
  235.  
  236. /*************************************
  237.  *
  238.  *    General MCR/68k debug
  239.  *
  240.  *************************************/
  241.  
  242. #if DEBUG_VIDEO
  243. void mcr68_debug(void)
  244. {
  245.     static FILE *f;
  246.     if (keyboard_pressed(KEYCODE_9))
  247.     {
  248.         int offs;
  249.  
  250.         if (!f) f = fopen("mcr.log", "w");
  251.         if (f)
  252.         {
  253.             fprintf(f, "\n\n=================================================================\n");
  254.             for (offs = 0; offs < videoram_size; offs += 4)
  255.             {
  256.                 fprintf(f, "%02X%02X ", LOW_BYTE(&videoram[offs + 2]), LOW_BYTE(&videoram[offs + 0]));
  257.                 if (offs % (32 * 4) == 31 * 4) fprintf(f, "\n");
  258.             }
  259.             fprintf(f, "\n\n");
  260.             for (offs = 0; offs < spriteram_size; offs += 8)
  261.                 fprintf(f, "Sprite %03d: %02X %02X %02X %02X\n", offs / 8,
  262.                     LOW_BYTE(&spriteram[offs + 0]),
  263.                     LOW_BYTE(&spriteram[offs + 2]),
  264.                     LOW_BYTE(&spriteram[offs + 4]),
  265.                     LOW_BYTE(&spriteram[offs + 6]));
  266.         }
  267.         fflush(f);
  268.     }
  269. }
  270. #endif
  271.  
  272.  
  273.  
  274. /*************************************
  275.  *
  276.  *    Zwackery palette RAM writes
  277.  *
  278.  *************************************/
  279.  
  280. WRITE_HANDLER( zwackery_paletteram_w )
  281. {
  282.     int oldword = READ_WORD(&paletteram[offset]);
  283.     int newword = COMBINE_WORD(oldword, data);
  284.     int r, g, b;
  285.  
  286.     WRITE_WORD(&paletteram[offset], newword);
  287.  
  288.     r = (~newword >> 10) & 31;
  289.     b = (~newword >> 5) & 31;
  290.     g = (~newword >> 0) & 31;
  291.  
  292.     /* up to 8 bits */
  293.     r = (r << 3) | (r >> 2);
  294.     g = (g << 3) | (g >> 2);
  295.     b = (b << 3) | (b >> 2);
  296.  
  297.     palette_change_color(offset / 2, r, g, b);
  298. }
  299.  
  300.  
  301.  
  302. /*************************************
  303.  *
  304.  *    Zwackery video RAM writes
  305.  *
  306.  *************************************/
  307.  
  308. WRITE_HANDLER( zwackery_videoram_w )
  309. {
  310.     int oldword = READ_WORD(&videoram[offset]);
  311.     int newword = COMBINE_WORD(oldword, data);
  312.  
  313.     if (oldword != newword)
  314.     {
  315.         dirtybuffer[offset & ~1] = 1;
  316.         WRITE_WORD(&videoram[offset], newword);
  317.     }
  318. }
  319.  
  320.  
  321.  
  322. /*************************************
  323.  *
  324.  *    Zwackery video RAM writes
  325.  *
  326.  *************************************/
  327.  
  328. WRITE_HANDLER( zwackery_spriteram_w )
  329. {
  330.     /* yech -- Zwackery relies on the upper 8 bits of a spriteram read being $ff! */
  331.     /* to make this happen we always write $ff in the upper 8 bits */
  332.     int oldword = READ_WORD(&spriteram[offset]);
  333.     int newword = COMBINE_WORD(oldword, data);
  334.     WRITE_WORD(&spriteram[offset], newword | 0xff00);
  335. }
  336.  
  337.  
  338.  
  339. /*************************************
  340.  *
  341.  *    Zwackery color data conversion
  342.  *
  343.  *************************************/
  344.  
  345. void zwackery_convert_color_prom(unsigned char *palette, unsigned short *colortable, const unsigned char *color_prom)
  346. {
  347.     const UINT8 *colordatabase = (const UINT8 *)memory_region(REGION_GFX3);
  348.     struct GfxElement *gfx0 = Machine->gfx[0];
  349.     struct GfxElement *gfx2 = Machine->gfx[2];
  350.     int code, y, x, ix;
  351.  
  352.     /* "colorize" each code */
  353.     for (code = 0; code < gfx0->total_elements; code++)
  354.     {
  355.         const UINT8 *coldata = colordatabase + code * 32;
  356.         UINT8 *gfxdata0 = gfx0->gfxdata + code * gfx0->char_modulo;
  357.         UINT8 *gfxdata2 = gfx2->gfxdata + code * gfx2->char_modulo;
  358.  
  359.         /* assume 16 rows */
  360.         for (y = 0; y < 16; y++)
  361.         {
  362.             const UINT8 *cd = coldata;
  363.             UINT8 *gd0 = gfxdata0;
  364.             UINT8 *gd2 = gfxdata2;
  365.  
  366.             /* 16 colums, in batches of 4 pixels */
  367.             for (x = 0; x < 16; x += 4)
  368.             {
  369.                 int pen0 = *cd++;
  370.                 int pen1 = *cd++;
  371.                 int tp0, tp1;
  372.  
  373.                 /* every 4 pixels gets its own foreground/background colors */
  374.                 for (ix = 0; ix < 4; ix++, gd0++)
  375.                     *gd0 = *gd0 ? pen1 : pen0;
  376.  
  377.                 /* for gfx 2, we convert all low-priority pens to 0 */
  378.                 tp0 = (pen0 & 0x80) ? pen0 : 0;
  379.                 tp1 = (pen1 & 0x80) ? pen1 : 0;
  380.                 for (ix = 0; ix < 4; ix++, gd2++)
  381.                     *gd2 = *gd2 ? tp1 : tp0;
  382.             }
  383.  
  384.             /* advance */
  385.             if (y % 4 == 3) coldata = cd;
  386.             gfxdata0 += gfx0->line_modulo;
  387.             gfxdata2 += gfx2->line_modulo;
  388.         }
  389.     }
  390. }
  391.  
  392.  
  393.  
  394. /*************************************
  395.  *
  396.  *    Zwackery background update
  397.  *
  398.  *************************************/
  399.  
  400. static void zwackery_mark_background(void)
  401. {
  402.     const UINT8 *colordatabase = (const UINT8 *)memory_region(REGION_GFX3);
  403.     int offs;
  404.  
  405.     /* for every character in the Video RAM, mark the colors */
  406.     for (offs = videoram_size - 2; offs >= 0; offs -= 2)
  407.     {
  408.         int data = READ_WORD(&videoram[offs]);
  409.         int color = (data >> 13) & 7;
  410.         int code = data & 0x3ff;
  411.         int i;
  412.  
  413.         /* get color data pointers */
  414.         const UINT8 *coldata = colordatabase + code * 32;
  415.         UINT8 *used_colors = &palette_used_colors[color << 8];
  416.  
  417.         /* each character uses up to 32 unique colors */
  418.         for (i = 0; i < 32; i++)
  419.             used_colors[*coldata++] = PALETTE_COLOR_VISIBLE;
  420.     }
  421. }
  422.  
  423.  
  424. static void zwackery_update_background(struct osd_bitmap *bitmap, int overrender)
  425. {
  426.     int offs;
  427.  
  428.     /* for every character in the Video RAM, check if it has been modified */
  429.     /* since last time and update it accordingly. */
  430.     for (offs = videoram_size - 2; offs >= 0; offs -= 2)
  431.     {
  432.         /* this works for overrendering as well, since the sprite code will mark */
  433.         /* intersecting tiles for us */
  434.         if (dirtybuffer[offs])
  435.         {
  436.             int data = READ_WORD(&videoram[offs]);
  437.             int mx = (offs / 2) % 32;
  438.             int my = (offs / 2) / 32;
  439.             int color = (data >> 13) & 7;
  440.             int code = data & 0x3ff;
  441.  
  442.             /* standard case: draw with no transparency */
  443.             if (!overrender)
  444.                 drawgfx(bitmap, Machine->gfx[0], code, color, data & 0x0800, data & 0x1000,
  445.                         16 * mx, 16 * my, &Machine->drv->visible_area, TRANSPARENCY_NONE, 0);
  446.  
  447.             /* overrender case: for non-zero colors, draw with transparency pen 0 */
  448.             /* we use gfx[2] here, which was generated above to have all low-priority */
  449.             /* colors set to pen 0 */
  450.             else if (color != 0)
  451.                 drawgfx(bitmap, Machine->gfx[2], code, color, data & 0x0800, data & 0x1000,
  452.                         16 * mx, 16 * my, &Machine->drv->visible_area, TRANSPARENCY_PEN, 0);
  453.  
  454. #if DEBUG_VIDEO
  455. if (show_bg_colors)
  456. {
  457.     char c = "01234567"[color];
  458.     drawgfx(bitmap, Machine->uifont, c, 1, 0, 0, 16 * mx + 0, 16 * my, 0, TRANSPARENCY_PEN, 0);
  459.     drawgfx(bitmap, Machine->uifont, c, 1, 0, 0, 16 * mx + 4, 16 * my, 0, TRANSPARENCY_PEN, 0);
  460.     drawgfx(bitmap, Machine->uifont, c, 0, 0, 0, 16 * mx + 2, 16 * my, 0, TRANSPARENCY_PEN, 0);
  461. }
  462. #endif
  463.  
  464.             /* only clear the dirty flag if we're not overrendering */
  465.             dirtybuffer[offs] = 0;
  466.         }
  467.     }
  468. }
  469.  
  470.  
  471.  
  472. /*************************************
  473.  *
  474.  *    Sprite update
  475.  *
  476.  *************************************/
  477.  
  478. static void zwackery_mark_sprites(void)
  479. {
  480.     UINT16 used[32];
  481.     int offs, i;
  482.  
  483.     /* clear the usage array */
  484.     memset(&used, 0, sizeof(used));
  485.  
  486.     /* loop over spriteram */
  487.     for (offs = 0; offs < spriteram_size; offs += 8)
  488.     {
  489.         int code, color, flags;
  490.  
  491.         /* get the code and skip if zero */
  492.         code = LOW_BYTE(&spriteram[offs + 4]);
  493.         if (code == 0)
  494.             continue;
  495.  
  496.         /* extract the flag bits and determine the color */
  497.         flags = LOW_BYTE(&spriteram[offs + 2]);
  498.         color = ((~flags >> 2) & 0x0f) | ((flags & 0x02) << 3);
  499.  
  500.         /* mark the appropriate pens */
  501.         used[color] |= Machine->gfx[1]->pen_usage[code];
  502.     }
  503.  
  504.     /* use the usage array to mark the global palette_used_colors */
  505.     for (offs = 0; offs < 32; offs++)
  506.     {
  507.         UINT16 u = used[offs];
  508.         if (u)
  509.         {
  510.             palette_used_colors[0x800 + offs * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  511.             for (i = 1; i < 16; i++)
  512.                 if (u & (1 << i))
  513.                     palette_used_colors[0x800 + offs * 16 + i] = PALETTE_COLOR_USED;
  514.         }
  515.     }
  516. }
  517.  
  518.  
  519. static void zwackery_update_sprites(struct osd_bitmap *bitmap, int priority)
  520. {
  521.     int offs;
  522.  
  523.     /* loop over sprite RAM */
  524.     for (offs = 0; offs < spriteram_size; offs += 8)
  525.     {
  526.         int code, color, flipx, flipy, x, y, sx, sy, xcount, ycount, flags;
  527.  
  528.         /* get the code and skip if zero */
  529.         code = LOW_BYTE(&spriteram[offs + 4]);
  530.         if (code == 0)
  531.             continue;
  532.  
  533.         /* extract the flag bits and determine the color */
  534.         flags = LOW_BYTE(&spriteram[offs + 2]);
  535.         color = ((~flags >> 2) & 0x0f) | ((flags & 0x02) << 3);
  536.  
  537.         /* for low priority, draw everything but color 7 */
  538.         if (!priority)
  539.         {
  540.             if (color == 7)
  541.                 continue;
  542.         }
  543.  
  544.         /* for high priority, only draw color 7 */
  545.         else
  546.         {
  547.             if (color != 7)
  548.                 continue;
  549.         }
  550.  
  551.         /* determine flipping and coordinates */
  552.         flipx = ~flags & 0x40;
  553.         flipy = flags & 0x80;
  554.         x = (231 - LOW_BYTE(&spriteram[offs + 6])) * 2;
  555.         y = (241 - LOW_BYTE(&spriteram[offs])) * 2;
  556.  
  557.         if (x <= -32) x += 512;
  558.  
  559.         /* draw the sprite */
  560.         drawgfx(bitmap, Machine->gfx[1], code, color, flipx, flipy, x, y,
  561.                 &Machine->drv->visible_area, TRANSPARENCY_PEN, 0);
  562.  
  563. #if DEBUG_VIDEO
  564. if (show_colors)
  565. {
  566.     char c = "0123456789ABCDEF"[color];
  567.     drawgfx(bitmap, Machine->uifont, c, 1, 0, 0, x + 8,  y + 8, 0, TRANSPARENCY_PEN, 0);
  568.     drawgfx(bitmap, Machine->uifont, c, 1, 0, 0, x + 12, y + 8, 0, TRANSPARENCY_PEN, 0);
  569.     drawgfx(bitmap, Machine->uifont, c, 0, 0, 0, x + 10, y + 8, 0, TRANSPARENCY_PEN, 0);
  570. }
  571. #endif
  572.  
  573.         /* sprites use color 0 for background pen and 8 for the 'under tile' pen.
  574.             The color 8 is used to cover over other sprites. */
  575.         if (Machine->gfx[1]->pen_usage[code] & 0x0100)
  576.         {
  577.             struct rectangle clip;
  578.  
  579.             clip.min_x = x;
  580.             clip.max_x = x + 31;
  581.             clip.min_y = y;
  582.             clip.max_y = y + 31;
  583.  
  584.             copybitmap(bitmap, tmpbitmap, 0, 0, 0, 0, &clip, TRANSPARENCY_THROUGH, Machine->pens[8 + color * 16]);
  585.         }
  586.  
  587.         /* mark tiles underneath as dirty for overrendering */
  588.         if (priority == 0)
  589.         {
  590.             sx = x / 16;
  591.             sy = y / 16;
  592.             xcount = (x & 15) ? 3 : 2;
  593.             ycount = (y & 15) ? 3 : 2;
  594.  
  595.             for (y = sy; y < sy + ycount; y++)
  596.                 for (x = sx; x < sx + xcount; x++)
  597.                     dirtybuffer[(32 * (y & 31) + (x & 31)) * 2] = 1;
  598.         }
  599.     }
  600. }
  601.  
  602.  
  603.  
  604. /*************************************
  605.  *
  606.  *    Zwackery MCR/68k update
  607.  *
  608.  *************************************/
  609.  
  610. void zwackery_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  611. {
  612. #if DEBUG_VIDEO
  613.     zwackery_debug();
  614. #endif
  615.  
  616.     /* mark the palette */
  617.     palette_init_used_colors();
  618.     zwackery_mark_background();
  619.     zwackery_mark_sprites();
  620.  
  621.     /* update palette */
  622.     if (palette_recalc())
  623.         memset(dirtybuffer, 1, videoram_size);
  624.  
  625.     /* draw the background */
  626.     zwackery_update_background(tmpbitmap, 0);
  627.  
  628.     /* copy it to the destination */
  629.     copybitmap(bitmap, tmpbitmap, 0, 0, 0, 0, &Machine->drv->visible_area, TRANSPARENCY_NONE, 0);
  630.  
  631.     /* draw the low-priority sprites */
  632.     zwackery_update_sprites(bitmap, 0);
  633.  
  634.     /* draw the background */
  635.     zwackery_update_background(bitmap, 1);
  636.  
  637.     /* draw the high-priority sprites */
  638.     zwackery_update_sprites(bitmap, 1);
  639. }
  640.  
  641.  
  642.  
  643. /*************************************
  644.  *
  645.  *    Zwackery debug
  646.  *
  647.  *************************************/
  648.  
  649. #if DEBUG_VIDEO
  650. void zwackery_debug(void)
  651. {
  652.     static int last_h_state;
  653.     static int last_l_state;
  654.     static FILE *f;
  655.     int i;
  656.  
  657.     if (keyboard_pressed(KEYCODE_CAPSLOCK))
  658.     {
  659.         if (!show_bg_colors) memset(dirtybuffer, 1, videoram_size);
  660.         show_bg_colors = 1;
  661.     }
  662.     else
  663.     {
  664.         if (show_bg_colors) memset(dirtybuffer, 1, videoram_size);
  665.         show_bg_colors = 0;
  666.     }
  667.  
  668.     if (keyboard_pressed(KEYCODE_9))
  669.     {
  670.         int offs;
  671.  
  672.         if (!f) f = fopen("mcr.log", "w");
  673.         if (f)
  674.         {
  675.             fprintf(f, "\n\n=================================================================\n");
  676.             for (offs = 0; offs < videoram_size; offs += 2)
  677.             {
  678.                 fprintf(f, "%04X ", READ_WORD(&videoram[offs]));
  679.                 if (offs % (32 * 2) == 31 * 2) fprintf(f, "\n");
  680.             }
  681.             fprintf(f, "\n\n");
  682.             for (offs = 0; offs < spriteram_size; offs += 8)
  683.                 fprintf(f, "Sprite %03d: %02X %02X %02X %02X\n", offs / 8,
  684.                     READ_WORD(&spriteram[offs + 0]),
  685.                     READ_WORD(&spriteram[offs + 2]),
  686.                     READ_WORD(&spriteram[offs + 4]),
  687.                     READ_WORD(&spriteram[offs + 6]));
  688.         }
  689.         fflush(f);
  690.     }
  691.  
  692.     show_colors = keyboard_pressed(KEYCODE_8);
  693.  
  694.     if (keyboard_pressed(KEYCODE_H))
  695.     {
  696.         last_h_state = 1;
  697.         for (i = 0; i < 2048; i++)
  698.             if (i & 0x80) palette_change_color(i, 255, 255, 255);
  699.     }
  700.     else if (last_h_state)
  701.     {
  702.         last_h_state = 0;
  703.         for (i = 0; i < 2048; i++)
  704.             if (i & 0x80)
  705.             {
  706.                 int word = READ_WORD(&paletteram[i * 2]);
  707.  
  708.                 int r = (~word >> 10) & 31;
  709.                 int b = (~word >> 5) & 31;
  710.                 int g = (~word >> 0) & 31;
  711.  
  712.                 /* up to 8 bits */
  713.                 r = (r << 3) | (r >> 2);
  714.                 g = (g << 3) | (g >> 2);
  715.                 b = (b << 3) | (b >> 2);
  716.  
  717.                 palette_change_color(i, r, g, b);
  718.             }
  719.     }
  720.  
  721.     if (keyboard_pressed(KEYCODE_L))
  722.     {
  723.         last_l_state = 1;
  724.         for (i = 0; i < 2048; i++)
  725.             if (!(i & 0x80)) palette_change_color(i, 255, 255, 255);
  726.     }
  727.     else if (last_l_state)
  728.     {
  729.         last_l_state = 0;
  730.         for (i = 0; i < 2048; i++)
  731.             if (!(i & 0x80))
  732.             {
  733.                 int word = READ_WORD(&paletteram[i * 2]);
  734.  
  735.                 int r = (~word >> 10) & 31;
  736.                 int b = (~word >> 5) & 31;
  737.                 int g = (~word >> 0) & 31;
  738.  
  739.                 /* up to 8 bits */
  740.                 r = (r << 3) | (r >> 2);
  741.                 g = (g << 3) | (g >> 2);
  742.                 b = (b << 3) | (b >> 2);
  743.  
  744.                 palette_change_color(i, r, g, b);
  745.             }
  746.     }
  747. }
  748. #endif
  749.  
  750.